/**
 * @file 来自zepto/touch.js, zepto自1.0后，已不默认打包此文件。
 * @import zepto.js
 */
//     Zepto.js
//     (c) 2010-2012 Thomas Fuchs
//     Zepto.js may be freely distributed under the MIT license.

; (function ($) {
    var touch = {},
      touchTimeout, tapTimeout, swipeTimeout,
      longTapDelay = 750, longTapTimeout

    function parentIfText(node) {
        return 'tagName' in node ? node : node.parentNode
    }

    function swipeDirection(x1, x2, y1, y2) {
        var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2)
        return xDelta >= yDelta ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
    }

    function longTap() {
        longTapTimeout = null
        if (touch.last) {
            touch.el.trigger('longTap')
            touch = {}
        }
    }

    function cancelLongTap() {
        if (longTapTimeout) clearTimeout(longTapTimeout)
        longTapTimeout = null
    }

    function cancelAll() {
        if (touchTimeout) clearTimeout(touchTimeout)
        if (tapTimeout) clearTimeout(tapTimeout)
        if (swipeTimeout) clearTimeout(swipeTimeout)
        if (longTapTimeout) clearTimeout(longTapTimeout)
        touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null
        touch = {}
    }

    function bindSwipe() {
        document.body.addEventListener("touchstart", touchStartHandler);
        document.body.addEventListener("touchmove", touchMoveHandler);
        document.body.addEventListener("touchend", touchEndHandler);
        document.body.addEventListener("touchcancel", cancelAll);
        window.addEventListener("scroll", cancelAll);
    }

    function removeSwipe() {
        document.body.removeEventListener("touchstart", touchStartHandler);
        document.body.removeEventListener("touchmove", touchMoveHandler);
        document.body.removeEventListener("touchend", touchEndHandler);
        document.body.removeEventListener("touchcancel", cancelAll);
        window.removeEventListener("scroll", cancelAll);
    }

    
    function multiTouchStartHandler(e) {
        
    }

    function multiTouchMoveHandler(e) {
        
    }

    function multiTouchEndHandler(e) {
        
    }

    function singleTouchStartHandler(e) {
        now = Date.now()
        delta = now - (touch.last || now)
        touch.el = $(parentIfText(e.touches[0].target))
        touchTimeout && clearTimeout(touchTimeout)
        touch.x1 = e.touches[0].pageX
        touch.y1 = e.touches[0].pageY
        if (delta > 0 && delta <= 250) touch.isDoubleTap = true
        touch.last = now
        longTapTimeout = setTimeout(longTap, longTapDelay)
    }

    function singleTouchMoveHandler(e) {
        cancelLongTap()
        touch.x2 = e.touches[0].pageX
        touch.y2 = e.touches[0].pageY
        if (Math.abs(touch.x1 - touch.x2) > 1)
            e.preventDefault()
    }

    function singleTouchEndHandler() {
        cancelLongTap()

        // swipe
        if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 1) ||
            (touch.y2 && Math.abs(touch.y1 - touch.y2) > 1))

            swipeTimeout = setTimeout(function () {
                $.swipeDirection = swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2);
                if (touch.el) {
                    touch.el.trigger('swipe')
                    touch.el.trigger('swipe' + $.swipeDirection)
                }
                touch = {}
            }, 0)

            // normal tap
        else if ('last' in touch)

            // delay by one tick so we can cancel the 'tap' event if 'scroll' fires
            // ('tap' fires before 'scroll')
            tapTimeout = setTimeout(function () {

                // trigger universal 'tap' with the option to cancelTouch()
                // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
                var event = $.Event('tap')
                event.cancelTouch = cancelAll
                touch.el.trigger(event)

                // trigger double tap immediately
                if (touch.isDoubleTap) {
                    touch.el.trigger('doubleTap')
                    touch = {}
                }

                    // trigger single tap after 250ms of inactivity
                else {
                    touchTimeout = setTimeout(function () {
                        touchTimeout = null
                        touch.el.trigger('singleTap')
                        touch = {}
                    }, 250)
                }

            }, 0)
    }

    var now, delta;
    function touchStartHandler(e) {
        if (e.touches.length > 1) {
            multiTouchStartHandler(e);
        } else {
            singleTouchStartHandler(e);
        }
    }
    function touchMoveHandler(e) {
        if (e.touches.length > 1) {
            multiTouchMoveHandler(e);
        } else {
            singleTouchMoveHandler(e);
        }
    }
    function touchEndHandler(e) {
        if (e.touches.length > 1) {
            multiTouchEndHandler(e);
        } else {
            singleTouchEndHandler(e);
        }
    }

    //$(document).ready(function () {
    //    bindSwipe();
    //})

    ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function (m) {
        $.fn[m] = function (callback) { return this.bind(m, callback) }
    })

    $.swipeOn = function () {
        bindSwipe();
    }

    $.swipeOff = function () {
        removeSwipe();
    }

})(Zepto);
